package cn.fx.basic.service.impl;

import cn.fx.basic.constant.RegisterConstant;
import cn.fx.basic.exception.BusinessException;
import cn.fx.basic.service.IVerifyCodeService;
import cn.fx.basic.util.StrUtils;
import cn.fx.basic.util.VerifyCodeUtils;
import cn.fx.user.domain.User;
import cn.fx.user.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.Map;
import java.util.concurrent.TimeUnit;

@Service
public class VerifyCodeServiceImpl implements IVerifyCodeService {

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private UserMapper userMapper;

    @Override
    public String getVerifyCode(String key) {
        //校验
        if(StringUtils.isEmpty(key)){
            throw new BusinessException("参数有误！");
        }

        //生成随机验证码
        String code = StrUtils.getComplexRandomString(4);

        //存入redis中，设置过期时间 3分钟
        redisTemplate.opsForValue().set(key,code,3, TimeUnit.MINUTES);

        //生成base64位字符串
        return VerifyCodeUtils.verifyCode(100,40,code);
    }

    @Override
    public void smsCode(Map<String, String> map) {

        String phone = map.get("phone"); //手机号
        String imageCode = map.get("imageCode"); //图形验证码
        String imageCodeKey = map.get("imageCodeKey"); //图形验证码对应的key值

        //校验，参数不能为空
        if(StringUtils.isEmpty(phone)
                || StringUtils.isEmpty(imageCode)
                || StringUtils.isEmpty(imageCodeKey)
        ){
            throw new BusinessException("参数不能为空");
        }

        //图形验证码校验
        Object obj = redisTemplate.opsForValue().get(imageCodeKey);
        if(obj == null){
            throw new BusinessException("图形验证码过期了，请重新获取输入");
        }
        //验证码不区分大小写
        if(!obj.toString().equalsIgnoreCase(imageCode)){
            throw new BusinessException("图形验证码输入错误，请重新输入");
        }

        //手机号是否被注册过
        User user = userMapper.findByPhone(phone);
        if(user != null){
            throw new BusinessException("手机号已经被注册，请直接登录");
        }

        /**
         * key: 手机号+业务键
         * value: code: 时间戳
         */
        //判断是否是第一次发送请求，或者验证码过期 从redis中取
        Object value = redisTemplate.opsForValue().get(phone + RegisterConstant.PHONEREGISTER);

        String code = null;
        //取不到，没有发送过，获取过期了，直接生成新的验证码保存到redis
        if(value == null){ // 没取到
            code = StrUtils.getComplexRandomString(4);
        } else {
            //取到了，判断是否超过一分钟
            String redisTime = value.toString().split(":")[1];
            long ltime = Long.parseLong(redisTime);

            //如果没超过一分钟，提示用户一分钟之内不能多次发送
            if(System.currentTimeMillis() - ltime < 60 * 1000){
                throw new BusinessException("一分钟内不能发送多次！");

            } else {
                //超过了一分钟，刷新过期时间
                code = value.toString().split(":")[0];
            }
        }


        //把code存入redis中
        redisTemplate.opsForValue().set(
                phone + RegisterConstant.PHONEREGISTER,
                code + ":" + System.currentTimeMillis(),
                3,
                TimeUnit.MINUTES);

        //发送短信给用户
        //SmsSendUtil.smsSend(phone,"您的验证码为: " + code + ",请在三分钟之内使用");
        //AliSmsSendUtil.smsSendCode(phone,"您的验证码为: " + code + ",请在三分钟之内使用");

        System.out.println("您的验证码为: " + code + ",请在三分钟之内使用");
    }

    @Override
    public void binderSmsCode(Map<String, String> map) {

            String phone = map.get("phone"); //手机号

            //校验，参数不能为空
            if(StringUtils.isEmpty(phone)
            ){
                throw new BusinessException("手机号不能为空");
            }

            /**
             * key: 手机号+业务键
             * value: code: 时间戳
             */
            //判断是否是第一次发送请求，或者验证码过期 从redis中取
            Object value = redisTemplate.opsForValue().get(phone + RegisterConstant.WXBINDER);

            String code = null;
            //取不到，没有发送过，获取过期了，直接生成新的验证码保存到redis
            if(value == null){ // 没取到
                code = StrUtils.getComplexRandomString(4);
            } else {
                //取到了，判断是否超过一分钟
                String redisTime = value.toString().split(":")[1];
                long ltime = Long.parseLong(redisTime);

                //如果没超过一分钟，提示用户一分钟之内不能多次发送
                if(System.currentTimeMillis() - ltime < 60 * 1000){
                    throw new BusinessException("一分钟内不能发送多次！");

                } else {
                    //超过了一分钟，刷新过期时间
                    code = value.toString().split(":")[0];
                }
            }


            //把code存入redis中
            redisTemplate.opsForValue().set(
                    phone + RegisterConstant.WXBINDER,
                    code + ":" + System.currentTimeMillis(),
                    3,
                    TimeUnit.MINUTES);

            //发送短信给用户
            //SmsSendUtil.smsSend(phone,"您的验证码为: " + code + ",请在三分钟之内使用");
            //AliSmsSendUtil.smsSendCode(phone,"您的验证码为: " + code + ",请在三分钟之内使用");

            System.out.println("您的验证码为: " + code + ",请在三分钟之内使用");

    }
}
